#pragma once

#include <string>
#include <vector>
#include <memory>
#include <functional>
#include <unordered_map>
#include "viml/debug_info.h"
#include "viml/value.h"

namespace viml {

// 前向声明
class VM;

/**
 * 调试器事件类型
 */
enum class DebugEvent {
    BREAKPOINT_HIT,         // 断点命中
    STEP_COMPLETE,          // 单步完成
    FUNCTION_ENTRY,         // 函数入口
    FUNCTION_EXIT,          // 函数出口
    EXCEPTION_THROWN,       // 异常抛出
    LINE_CHANGE,            // 行号改变
    VM_PAUSED,              // 虚拟机暂停
    VM_HALTED,              // 虚拟机停止
};

/**
 * 调试器状态
 */
enum class DebuggerState {
    INACTIVE,               // 未激活
    ACTIVE,                 // 激活（等待）
    RUNNING,                // 运行中
    PAUSED,                 // 已暂停
    STEP_MODE,              // 单步模式
    STEPPING_OVER,          // 单步跳过
    STEPPING_IN,            // 单步进入
    STEPPING_OUT,           // 单步跳出
};

/**
 * 调试器事件信息
 */
struct DebugEventInfo {
    DebugEvent event;                    // 事件类型
    size_t pc;                          // 程序计数器
    int line;                           // 行号
    std::string function;               // 当前函数名
    std::string message;                // 附加信息
    std::vector<Value> call_stack;      // 调用栈
    std::unordered_map<std::string, Value> variables; // 变量值

    DebugEventInfo(DebugEvent e, size_t pc_addr = 0, int ln = 0, const std::string& func = "")
        : event(e), pc(pc_addr), line(ln), function(func) {}
};

/**
 * 调试器回调函数类型
 */
using DebugCallback = std::function<void(const DebugEventInfo&)>;

/**
 * 变量监视器
 */
class VariableWatcher {
private:
    std::string variable_name;
    DebugCallback callback;
    Value last_value;
    bool is_active;

public:
    VariableWatcher(const std::string& name, DebugCallback cb)
        : variable_name(name), callback(cb), is_active(true) {}

    void update(const Value& current_value) {
        if (!is_active) return;

        if (!(current_value == last_value)) {
            DebugEventInfo info(DebugEvent::LINE_CHANGE);
            info.message = "变量值改变: " + variable_name;
            info.variables[variable_name] = current_value;

            if (callback) {
                callback(info);
            }
            last_value = current_value;
        }
    }

    void set_active(bool active) { is_active = active; }
    bool is_watcher_active() const { return is_active; }
    const std::string& get_variable_name() const { return variable_name; }
};

/**
 * 主调试器类
 *
 * 提供完整的调试功能，包括：
 * - 断点管理
 * - 单步调试
 * - 变量监视
 * - 调用栈检查
 * - 事件处理
 */
class Debugger : public std::enable_shared_from_this<Debugger> {
private:
    std::shared_ptr<DebugInfo> debug_info;      // 调试信息
    std::shared_ptr<VM> vm;                      // 虚拟机实例
    DebuggerState state;                        // 调试器状态

    // 单步调试控制
    bool step_mode_enabled;
    bool step_over_enabled;
    bool step_into_enabled;
    bool step_out_enabled;
    size_t step_start_pc;
    size_t step_start_stack_depth;
    std::string step_function_name;

    // 事件处理
    std::vector<DebugCallback> event_callbacks;
    std::vector<std::unique_ptr<VariableWatcher>> variable_watchers;

    // 运行时数据
    std::vector<std::string> current_call_stack;
    std::unordered_map<std::string, Value> current_variables;
    size_t current_pc;
    std::string current_function;

    // 配置选项
    bool auto_load_source;
    bool show_instruction_disassembly;
    bool show_variable_values_on_stop;
    bool break_on_exception;
    bool trace_mode;

public:
    Debugger(std::shared_ptr<VM> virtual_machine = nullptr);
    ~Debugger() = default;

    // 禁用拷贝构造和赋值
    Debugger(const Debugger&) = delete;
    Debugger& operator=(const Debugger&) = delete;

    // 虚拟机管理
    void set_vm(std::shared_ptr<VM> virtual_machine);
    std::shared_ptr<VM> get_vm() const { return vm; }
    void attach_to_vm();
    void detach_from_vm();

    // 调试信息管理
    void set_debug_info(std::shared_ptr<DebugInfo> info);
    std::shared_ptr<DebugInfo> get_debug_info() const { return debug_info; }
    bool load_debug_info(const std::string& filename);

    // 状态管理
    DebuggerState get_state() const { return state; }
    bool is_active() const { return state != DebuggerState::INACTIVE; }
    bool is_paused() const { return state == DebuggerState::PAUSED; }
    bool is_running() const { return state == DebuggerState::RUNNING; }
    bool is_in_step_mode() const {
        return state == DebuggerState::STEP_MODE ||
               state == DebuggerState::STEPPING_OVER ||
               state == DebuggerState::STEPPING_IN ||
               state == DebuggerState::STEPPING_OUT;
    }

    // 调试器控制接口
    bool should_pause() const;
    bool check_breakpoint(size_t pc, int line);
    void on_vm_paused(size_t pc, int line);
    void on_breakpoint_hit(size_t pc, int line);

    // 启动和停止
    bool start();
    void stop();
    void pause();
    void resume();
    void reset();

    // 断点管理
    size_t set_breakpoint(int line, const std::string& condition = "");
    size_t set_breakpoint(const std::string& file, int line, const std::string& condition = "");
    size_t set_breakpoint(size_t pc, const std::string& condition = "");
    bool remove_breakpoint(size_t breakpoint_id);
    bool remove_breakpoint(int line);
    bool remove_breakpoint(const std::string& file, int line);
    bool enable_breakpoint(size_t breakpoint_id, bool enabled = true);
    bool disable_breakpoint(size_t breakpoint_id);
    void clear_all_breakpoints();
    std::vector<const BreakpointInfo*> get_all_breakpoints() const;
    std::vector<const BreakpointInfo*> get_enabled_breakpoints() const;
    const BreakpointInfo* get_breakpoint(size_t breakpoint_id) const;
    bool has_breakpoint_at(int line) const;
    bool has_breakpoint_at(const std::string& file, int line) const;

    // 单步调试
    void step_into();
    void step_over();
    void step_out();
    void step_next();
    void continue_execution();
    void run_to_line(int line);
    void run_to_function(const std::string& function_name);

    // 执行控制
    void execute_instruction(size_t pc);
    void handle_vm_state_change();
    void process_debug_event(const DebugEventInfo& event);

    // 变量监视
    size_t add_variable_watcher(const std::string& variable_name, DebugCallback callback);
    bool remove_variable_watcher(size_t watcher_id);
    void clear_variable_watchers();
    void update_variable_values();
    Value get_variable_value(const std::string& name) const;
    std::unordered_map<std::string, Value> get_all_variables() const;
    std::vector<std::string> get_variable_names() const;

    // 调用栈管理
    std::vector<std::string> get_call_stack() const;
    size_t get_stack_depth() const;
    std::string get_current_function() const { return current_function; }
    size_t get_current_pc() const { return current_pc; }
    int get_current_line() const;

    // 源码信息
    std::string get_source_file() const;
    std::string get_source_line(int line) const;
    int get_line_count() const;
    std::vector<int> get_executable_lines() const;
    bool is_executable_line(int line) const;
    std::string get_current_source_line() const;

    // 事件处理
    void add_event_callback(DebugCallback callback);
    void remove_event_callback(const DebugCallback& callback);
    void clear_event_callbacks();
    void trigger_event(const DebugEventInfo& event);

    // 配置选项
    void set_auto_load_source(bool enabled) { auto_load_source = enabled; }
    bool is_auto_load_source_enabled() const { return auto_load_source; }
    void set_show_instruction_disassembly(bool enabled) { show_instruction_disassembly = enabled; }
    bool is_show_instruction_disassembly_enabled() const { return show_instruction_disassembly; }
    void set_show_variable_values_on_stop(bool enabled) { show_variable_values_on_stop = enabled; }
    bool is_show_variable_values_on_stop_enabled() const { return show_variable_values_on_stop; }
    void set_break_on_exception(bool enabled) { break_on_exception = enabled; }
    bool is_break_on_exception_enabled() const { return break_on_exception; }
    void set_trace_mode(bool enabled) { trace_mode = enabled; }
    bool is_trace_mode_enabled() const { return trace_mode; }

    // 调试输出和格式化
    std::string format_current_location() const;
    std::string format_call_stack() const;
    std::string format_variables() const;
    std::string format_breakpoints() const;
    std::string format_current_state() const;

    // 调试辅助方法
    void show_help() const;
    void show_backtrace() const;
    void show_locals() const;
    void show_globals() const;
    void show_breakpoints_list() const;
    void show_source(int context_lines = 5) const;
    void disassemble_current_function() const;

    // 统计信息
    struct DebuggerStatistics {
        size_t breakpoints_hit = 0;
        size_t steps_taken = 0;
        size_t variables_watched = 0;
        size_t events_fired = 0;
        double debugging_time = 0.0;
    };

    DebuggerStatistics get_statistics() const;
    void reset_statistics();

    // 错误处理
    struct DebuggerError {
        std::string message;
        std::string context;
        size_t line;

        DebuggerError(const std::string& msg, const std::string& ctx = "", size_t ln = 0)
            : message(msg), context(ctx), line(ln) {}
    };

    std::vector<DebuggerError> get_errors() const;
    void clear_errors();

public:
    // VM回调方法（需要被VM调用）
    void on_vm_instruction_execute(size_t pc);
    void on_vm_function_call(const std::string& function_name);
    void on_vm_function_return(const std::string& function_name);
    void on_vm_exception(const std::string& error);

private:
    std::vector<DebuggerError> errors;
    DebuggerStatistics stats;

    // 内部辅助方法
    void initialize_debugger();
    void cleanup_debugger();
    void update_current_context();
    void check_breakpoints();
    void check_watchpoints();
    bool should_step_continue() const;
    void handle_step_completion();
    void on_breakpoint_hit(const BreakpointInfo* bp);
    void on_step_complete();
    void on_function_entry(const std::string& function_name);
    void on_function_exit(const std::string& function_name);
    void on_exception_thrown(const std::string& error_message);
    void on_line_changed(int line);

    // 状态转换
    void set_state(DebuggerState new_state);
    void transition_to_running();
    void transition_to_paused();
    void transition_to_step_mode();

    // VM回调处理
    void setup_vm_callbacks();
    void cleanup_vm_callbacks();

    // 内部工具方法
    std::string format_value(const Value& value) const;
    std::string format_variable_info(const std::string& name, const Value& value) const;
    size_t generate_unique_watcher_id();
    bool is_in_same_function(size_t pc1, size_t pc2) const;
    size_t get_function_stack_depth(const std::string& function_name) const;
};

} // namespace viml